Skip to content

docs(deploy): by-reference deploys, sealed credentials, and server-side SSH keygen (v5.2.3 / v5.2.4) - #636

Merged
dawsontoth merged 4 commits into
mainfrom
claude/deploy-by-ref-shipped
Aug 25, 2026
Merged

docs(deploy): by-reference deploys, sealed credentials, and server-side SSH keygen (v5.2.3 / v5.2.4)#636
dawsontoth merged 4 commits into
mainfrom
claude/deploy-by-ref-shipped

Conversation

@dawsontoth

Copy link
Copy Markdown
Contributor

Documents the private-source deploy workflow that has already shipped: by-reference deploys and sealed deploy credentials in v5.2.3, and add_ssh_key generate in v5.2.4.

Split out of #599, which remains gated on harper#1849 — still a draft. There is no reason for docs describing shipped behavior to wait on unshipped work, and this content had been blocked that way for weeks.

Supersedes #617, whose corrections are folded in here rather than layered on top, so there is no window where the published page describes a parameter form the CLI rejects.

What shipped, and where it landed

Surface Upstream Ships in
deploy by_ref=true / ref= / credential=true harper#1850 v5.2.3
deploy setup=true harper#1851 v5.2.3
add_ssh_key generate: true harper-pro#594 v5.2.4

Each verified with git tag --contains on the merge commit rather than from a branch's package.json — the latter is what previously left this content badged v5.2.0 for a month.

For the human reviewer

  1. The credential parameter form changed, and the old docs were wrong. docs(deploy): two-phase deploy, revert, by-reference deploys, and OIDC trusted publishing #599's original text said credential takes a git host (credential=github.com). resolveCredentialHost now rejects an explicitly named host that does not match the package's, with an error telling you to use credential=true. Publishing the old form would have documented a rejected invocation. This is the main reason the split is worth the churn rather than waiting.
  2. The SSH-key encryption guarantee is qualified rather than absolute. sealSSHKey still falls back to storing and replicating the private key in plaintext with only a WARN when no secret custody is registered, and that fallback is deliberate — SSH keys predate custody. So the docs say encryption at rest is a property of your configuration, not of the operation. That reads as a weaker promise than we might want to make; it is the accurate one. Custody is present by default and the note says so.
  3. A revert_component cross-reference was deliberately left behind. The credential section previously pointed at revert_component for the no-credential rollback path. That operation is unshipped, so the reference stays on docs(deploy): two-phase deploy, revert, by-reference deploys, and OIDC trusted publishing #599 — the build caught it as a dangling anchor when it came across, which is a good argument for the split.
  4. Scope judgment: SSH keygen is a different feature from by_ref, and I pulled it in anyway because the same rule applies — it is shipped and was blocked by a draft. If you would rather it rode with docs(deploy): two-phase deploy, revert, by-reference deploys, and OIDC trusted publishing #599, it is a clean revert of one commit.

Verification

Docs-only; per AGENTS.md the build is the end-to-end check. At head: npm run format:check clean, npm run build succeeds. The build reports two broken anchors, both pre-existing on main and neither in a file this PR touches — confirmed by building main with these changes stashed.

Behavior verified against harper v5.2.4 source, not against the PRs that introduced it:

Claim Source
credential=true derives the package host; a mismatched host is rejected resolveCredentialHost
Refs resolve locally, then on the remote, then fail closed resolveExplicitRef
Only refs/heads/* and refs/tags/* are fetchable assertCloneableRefNamespace
The unpushed-commit check is skipped under Actions bin/cliOperations.ts (GITHUB_SHA guard)
A pull_request run deploys the PR head, not the merge commit resolveActionsPullRequestHead
deploy setup=true supports exactly github and npm, and needs super_user bin/deploySetup.ts, utility/operation_authorization.ts
Keygen is in-process; plaintext fallback without custody security/sshKeyGeneration.ts, sealSSHKey

Notes

  • No companion marker — everything here is shipped, so nothing gates it.
  • Release notes go in 5.2.md with each entry labelled by the patch that shipped it, since this repo keeps one page per minor and points patches at GitHub releases. A patch-shipped feature is otherwise undiscoverable from the docs.

Description drafted by Claude Code (Opus 5).

Splits the shipped half of #599 out so it can merge on its own. Everything here
documents behavior in **v5.2.3** — `git tag --contains` on harper#1850's and
harper#1851's merge commits returns v5.2.3 and v5.2.4 — while #599 is gated on
harper#1849, still a draft. Accurate docs for a shipped feature should not wait
on unshipped work.

Carries the corrected text, not #599's original: the corrections that lived in
#617 are folded in here, so there is no window where the published page describes
the superseded parameter form.

- **Deploying by Reference** — `harper deploy by_ref=true`, `ref=`,
  `credential=true`. A reference pins to a resolved SHA: refs resolve from the
  local checkout, then from the remote when it is absent (a shallow CI clone
  usually has neither), and the deploy fails closed if neither can name a commit,
  because peers resolve the package independently. A ref must also name something
  a clone can fetch — `refs/heads/*` or `refs/tags/*` — so `refs/pull/123/head`
  is rejected up front even where the local checkout resolves it. A pinned SHA
  fixes the source revision, not the built artifact.
- **`credential=true`** derives the host from the package, so the credential
  always matches the clone it authenticates; an explicitly named host that does
  not match is rejected rather than silently unused.
- **GitHub Actions behavior** — the unpushed-commit check is skipped there (the
  runner's checkout is not a branch `git branch -r --contains` can see) while the
  dirty-tree warning still applies, and a `pull_request` run deploys the PR's
  head commit rather than the merge commit the runner checks out.
- **Provisioning a Deploy Credential** — `harper deploy setup=true`, the
  client-side sealing flow, the two providers it supports, and that it needs
  super_user because it calls `get_secrets_public_key` and `set_secret`.
- `reference/security/secrets.md` points its private-source section at the CLI
  flow, and `5.2.md` gains the two release-note entries.

The `revert_component` cross-reference from the credential section is deliberately
left on #599: `revert_component` is unshipped, and the build caught the dangling
anchor when it came across.
Same reasoning as the by_ref content: harper-pro#594 merged 2026-08-20 and
`git tag --contains` puts it in **v5.2.4**, so it is shipped and should not wait
on harper#1849.

- `generate: true` mints an ed25519 keypair on the node and returns only the
  public half, so a deploy key's private half never travels in a request body,
  shell history, or CI log. Generation is in-process (`node:crypto`), needing no
  `ssh-keygen` binary on the host.
- `public_key` comes back only on the generating call — Harper does not retain
  it — so the recovery path is delete-and-regenerate, since `update_ssh_key`
  cannot mint.
- The encryption-at-rest claim is qualified rather than absolute. `sealSSHKey`
  falls back to storing and replicating the private key in **plaintext** with only
  a WARN when no secret custody is registered, and that fallback is deliberate —
  SSH keys predate custody. So it is a property of the deployment's
  configuration, not of the operation, which matters most for `generate: true`
  because that reads as though the key could never be exposed. Custody is present
  by default, and the note says so rather than implying the risk is likely.

Also restores the 5.2.4 release-note entry, which I dropped when I took main's
`5.2.md` wholesale during the #599 merge — the same whole-file resolution hazard
that cost content once already in this session. Verifying the file matched main
confirmed the take succeeded but said nothing about what #599 uniquely added.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Harper documentation and release notes to cover new features, including deploying by git reference, provisioning sealed deploy credentials with client-side encryption, and server-side SSH key generation. The review feedback suggests resolving a duplicate configuration header in the release notes, clarifying ambiguous phrasing regarding when a reference is sent to the cluster, and using the standard <VersionBadge> component in the secrets documentation for consistency.

Comment thread release-notes/v5-lincoln/5.2.md Outdated
Comment thread reference/components/applications.md Outdated
Comment thread reference/security/secrets.md
@github-actions
github-actions Bot temporarily deployed to pr-636 August 25, 2026 15:08 Inactive
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-636

This preview will update automatically when you push new commits.

dawsontoth added a commit that referenced this pull request Aug 25, 2026
Removes what #636 now owns, so this PR is purely surface gated on
harper#1849 (draft) or unreleased:

- `reference/components/applications.md` — Deploying by Reference and
  Provisioning a Deploy Credential (both v5.2.3). The page returns to Package
  Sources followed by Dependency Management.
- `reference/operations-api/operations.md` — the `add_ssh_key` section reverts to
  main's, handing the `generate` subsection and its custody caveat (v5.2.4) over.
- `reference/security/secrets.md` — the `deploy setup=true` pointer.

One point was relocated rather than dropped. The credential section carried a
note that rolling back needs no credential, which is a fact about
`revert_component` rather than about provisioning, and `revert_component` stays
here. It now sits in that operation's own docs, phrased for why it matters: a
revert re-fetches nothing, so it still works when the token or deploy key that
installed the current version has expired or been revoked — which is often the
situation you are in when you need to roll back.

What remains is two-phase deploy, `revert_component`, the deployment lifecycle
and retention, the CLI stage/activate/revert rows, and OIDC.
Two of gemini's three findings on #636.

The duplicate `## Configuration` in `5.2.md` is mine: extracting the two 5.2.3
release-note entries by line range swept up the following section heading with
them, so the merged file carried it twice. Removed. Extracting by heading
boundary rather than line number would have avoided it — the same lesson as the
`add_ssh_key` extraction earlier, where an off-by-one line range grabbed a
neighbouring section.

"Resolved to a commit SHA before it ships" is genuinely ambiguous — "ships" reads
as a software release in a paragraph that is otherwise about git refs. Now
"before it is sent to the cluster", which is what actually happens.

Declining the third: it asks for `<VersionBadge version="v5.2.3" />` in place of
the inline `(v5.2.3+)` in `secrets.md`. That text sits mid-sentence in prose, and
CONTRIBUTING.md is explicit — "using the component mid-sentence is awkward.
Reserve `<VersionBadge>` for standalone placement after headings." The exact patch
version it also asks for is already there.
@dawsontoth
dawsontoth marked this pull request as ready for review August 25, 2026 15:12
@dawsontoth
dawsontoth requested a review from a team as a code owner August 25, 2026 15:12
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-636

This preview will update automatically when you push new commits.

@github-actions
github-actions Bot temporarily deployed to pr-636 August 25, 2026 15:13 Inactive
Comment thread reference/components/applications.md Outdated
Per @cb1kenobi: the flow also calls `grant_secret` (bin/deploySetup.ts:130,
step 5 of its header comment), which I omitted. It is equally SU-only
(utility/operation_authorization.ts:345), so the guidance was right and only the
list was short.

Worth noting the omission is not random — my own text three paragraphs above
describes the flow as five steps including grant_secret, so the call list
contradicted the flow description on the same page.
@dawsontoth
dawsontoth requested a review from cb1kenobi August 25, 2026 16:08
@github-actions

Copy link
Copy Markdown

🚀 Preview Deployment

Your preview deployment is ready!

🔗 Preview URL: https://preview.harper-documentation.harperfabric.com/pr-636

This preview will update automatically when you push new commits.

@github-actions
github-actions Bot temporarily deployed to pr-636 August 25, 2026 16:11 Inactive
@cb1kenobi

Copy link
Copy Markdown
Member

Reviewed e38eaff4 — no issues found. This PR looks good, nice job!

Re-review scope: 1 new commit since 8de3ed99 (e38eaff4, by @dawsontoth), touching reference/components/applications.md (1 line changed). Confirmed via git merge-base --is-ancestor that 8de3ed99 is a direct ancestor of e38eaff4 — a clean fast-forward, not a rebase or merge — so the prior 0 Critical / 0 High / 0 Medium stands unchanged, and the one open Nit is resolved.

The Nit (grant_secret missing from the SU-only call list) is fixed: the line now reads "It calls get_secrets_public_key, set_secret, and grant_secret, all of which require super_user". Verified independently against source at v5.2.4: grant_secret is issued at bin/deploySetup.ts:130 (storeSealedSecret) and registered requires_su: true at utility/operation_authorization.ts:345 (secretOperations.grantSecret.name) alongside set_secret and get_secrets_public_key. No overstatement — the doc's claim matches the code exactly.

Everything else on the page is untouched by this push, so it wasn't re-verified in this pass (already confirmed clean at 8de3ed99).


Generated by Barber AI

@dawsontoth
dawsontoth merged commit 6bf676d into main Aug 25, 2026
7 checks passed
dawsontoth added a commit that referenced this pull request Aug 25, 2026
Two of gemini's three findings on #636.

The duplicate `## Configuration` in `5.2.md` is mine: extracting the two 5.2.3
release-note entries by line range swept up the following section heading with
them, so the merged file carried it twice. Removed. Extracting by heading
boundary rather than line number would have avoided it — the same lesson as the
`add_ssh_key` extraction earlier, where an off-by-one line range grabbed a
neighbouring section.

"Resolved to a commit SHA before it ships" is genuinely ambiguous — "ships" reads
as a software release in a paragraph that is otherwise about git refs. Now
"before it is sent to the cluster", which is what actually happens.

Declining the third: it asks for `<VersionBadge version="v5.2.3" />` in place of
the inline `(v5.2.3+)` in `secrets.md`. That text sits mid-sentence in prose, and
CONTRIBUTING.md is explicit — "using the component mid-sentence is awkward.
Reserve `<VersionBadge>` for standalone placement after headings." The exact patch
version it also asks for is already there.
@dawsontoth
dawsontoth deleted the claude/deploy-by-ref-shipped branch August 25, 2026 16:21
@github-actions

Copy link
Copy Markdown

🧹 Preview Cleanup

The preview deployment for this PR has been removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants